# CSS&HTML精选面试题

# 元素水平垂直居中的方式

不同图片格式区别

# 居中为什么尽量使⽤ transform(为什么不使⽤marginLeft/Top)**

在居中元素时,使用 transform 的主要原因是它可以提供更好的性能和更灵活的布局控制,相比于使用 marginLeft 和 marginTop

以下是使用 transform 进行居中的几个优势:

  1. 性能优化:transform 属性可以触发 GPU 加速,这意味着浏览器可以使用硬件加速来处理元素的渲染,从而提高性能。相比之下,使用 marginLeft 和 marginTop 进行居中可能会导致页面的重排和重绘,性能较差。
  2. 灵活的布局控制:transform 属性可以与其他布局属性(如 positiondisplay 等)结合使用,提供更灵活的布局控制。例如,可以将元素设置为绝对定位(position: absolute)并使用 transform 属性进行居中,这样可以在不影响其他布局的情况下实现居中效果。
  3. 元素尺寸不影响布局:使用 transform 进行居中时,元素的尺寸不会影响其在布局中的位置。这意味着可以轻松地调整元素的大小而不会破坏居中效果。相比之下,使用 marginLeft 和 marginTop 进行居中时,元素的尺寸会影响其在布局中的位置,可能需要进行额外的计算和调整。

# CSS3 动画的实现方式有哪些,动手写一下将一个 div 在 1s 内移动 300px?

css3 实现动画主要有 3 种方式

  • transition 过渡动画
  • transform 2D 和 3D 转换
  • animation 自定义动画
 /* transition属性动画结合transform变化属性,实现元素移动一段距离的动画 */
#transitonDiv:hover {
    transition: all 1s ease-in-out;
    -webkit-transition: all 1s ease-in-out;
    -moz-transition: all 1s ease-in-out;
    -o-transition: all 1s ease-in-out;

    transform: translateX(300px);
    -ms-transform: translateX(300px);
    -moz-transform: translateX(300px);
    -webkit-transform: translateX(300px);
    -o-transform: translateX(300px);
}

/* 通过animation属性,实现逐帧动画 */
#animationDiv:hover {
    animation: animName 1s ease-in-out;
    -webkit-animation: animName 1s ease-in-out;
    -moz-animation: animName 1s ease-in-out;
    -o-animation: animName 1s ease-in-out;
}

/* 定义关键帧 */
@keyframes animName {
    0% {
        transform: translateX(0px);
    }
    30% {
        transform: translateX(100px);
    }
    60% {
        transform: translateX(200px);
    }
    100% {
        transform: translateX(300px);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

此外还可以 window.requestAnimationFrame() 实现:

const element = document.getElementById('e');
let start;

function render(timestamp) {
  if (start === undefined) {
  	start = timestamp;
  }
  const elapsed = timestamp - start;

  //这里使用`Math.min()`确保元素刚好停在300px的位置。
  element.style.transform = 'translateX(' + Math.min(0.3 * elapsed, 300) + 'px)';
  console.log(element.style.transform)

  if (elapsed < 1000) { // 在1秒后停止动画
    window.requestAnimationFrame(render);
  }
}

window.requestAnimationFrame(render);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 所有 css3 的动画都能用 GPU 加速么?

在 css 中,只有 3D 转换、opacity 透明、filter 滤镜和添加了 will-change 属性的元素,浏览器才会开启硬件(GPU)加速。

  • 不过如果我们想要 2D、过渡等动画也能开启硬件加速,我们可以通过给这些元素加上transform: translateZ(0); 或transform: translate3d(0,0,0);来诱导浏览器开启硬件加速,但是我们不能滥用。

  • 也可能通过添加 will-change 来实现。

为什么需要 GPU 硬件加速?

  • CSS3 动画在移动多终端设备场景下,相⽐ PC 会⾯对更多的性能问题,主要体现在动画的卡顿与闪烁。
  • 我们可以通过 GPU 硬件加速来解决这个问题

CPU 、GPU、硬件加速的关系?

  • 硬件加速意味着图形处理单元(GPU)会协助你的浏览器渲染网页,做一些繁重的工作,而不是把这些工作全部丢给中央处理单元(CPU)来完成。
  • 当一个 CSS 操作被硬件加速时,它的速度也会因为页面的渲染速度变快而得到提升。

CPU 和 GPU 都是处理单元

  • CPU 位于计算机的主板上,它被称为计算机的大脑。GPU 位于计算机的显卡上,负责处理和渲染图像
  • 此外,GPU 是专门为执行复杂的数学和几何计算而设计的,这些计算也是图形渲染的必要条件 -因此,将操作丢给 GPU 处理可以产生巨大的性能提升,也可以减少移动设备上的 CPU 争用。

硬件加速(又称 GPU 加速)

  • 依赖于浏览器渲染页面时使用的分层模型。
  • 当对页面上的元素进行某些操作(比如 3D 变换)时,该元素会被移动到属于它自己的“图层”,在那里它可以独立于页面的其他部分进行渲染,并在之后被合成(画到屏幕上)。
  • 这样就隔离了内容的渲染,如果该元素的变换是帧之间唯一的变化,那么页面的其他部分就不必重新渲染,这样往往能够提供明显的速度优势。
  • 不过这里需要说明一下:只有 3D 变换拥有属于自己的图层,2D 变换没有。

CSS 的 animation、transform 和 transition 不会自动进行 GPU 加速,一般是由浏览器缓慢的软件渲染引擎执行。 然而有些浏览器通过某些属性提供硬件加速,以获得更好的渲染性能。

开启 GPU 硬件加速可能触发的问题

硬件加速操作会创建一个所谓的合成渲染层(compositor layer),并上传到 GPU 进行合成。

然而,强行创造一个图层并不能解决某些页面上的性能瓶颈。

  • 虽然图层创建技术可以提升页面速度,但有一定代价:它们会占用系统 RAM 和 GPU 上的内存(在移动设备上很有限),而且拥有大量的图层会产生不好的影响(尤其是在移动设备上)
  • 所以必须明智地使用它们,确保其可以真正帮助页面性能,而且性能瓶颈不是由你页面上的其他操作造成的。

经过-webkit-transform: transition3d/translateZ 开启 GPU 硬件加速以后,有些时候可能会致使浏览器频繁闪烁或抖动,能够尝试如下办法解决之:

-webkit-backface-visibility: hidden; /* 各种前缀都要考虑,此处省略 */
-webkit-perspective: 1000; /* 各种前缀都要考虑,此处省略 */
1
2

# 如何画一个三角形

不同图片格式区别

<style>
  .triangle {
    width: 0;
    border: 50px solid transparent; /*边框颜色为透明*/
    border-left-color: 50px solid blue; /*左三角形*/
  }
</style>
<body>
  <div class="triangle"></div>
</body>
1
2
3
4
5
6
7
8
9
10

# css选择器分类

基本的: 1.id选择器(id="name") 2.类选择器(class="head") 3.标签选择器(body, div, ul, li) 4.全局选择器(*) 复杂的: 1.组合选择器(.head .head_logo) 2.后代选择器 (#head .nav ul li 从父集到子孙集) 3.群组选择器 (div, span, img {color:Red} 具有相同样式的标签分组显示) 4.继承选择器 5.伪类选择器(链接样式,a元素的伪类) 6.子选择器(div>p, 带大于号>) 7.CSS相邻相邻兄弟选择器(h1+p, 带加号+)

# 使元素消失的方法有哪些?

  • 1.opacity:0,该元素隐藏起来了,但不会改变页面布局,并且,如果该元素已经绑定了一些事件,如click事件也能触发
  • 2.visibility:hidden,该元素隐藏起来了,但不会改变页面布局,但是不会触发该元素已经绑定的事件
  • 3.display:none, 把元素隐藏起来,并且会改变页面布局,可以理解成在页面中把该元素删掉
  • 4.z-index=-999,让元素低于页面基本元素的层级
  • 5.设置 posoition 为 absolute 或 fixed,通过设置 top、left 等值,将其移出可视区域。
  • 6.利用 transfrom:transform: scale(0);``transform: translateX(-99999px);
  • 7.设置大小为0:height: 0;width: 0;font-size:0;overflow: hidden;
  • 8.clip-path 裁剪
  • 9.aria-hidden 属性,读屏软件不可读,占据空间,可见。
  • hidden 属性,HTML5 新增属性,相当于 display: none;<div hidden></div>

# 如何开启GPU加速

  • translateZ() 或者 translate3d()

  • <video><canvas> 标签

  • CSS filters

  • will-change

  • 元素覆盖时,比如使用了 z-index 属性

  • 优点:使用 transform、opacity、filters、will-change 等属性时,会直接在 GPU 中完成处理,这些属性的变化不会引起回流重绘

  • 缺点:GPU 渲染字体会导致字体模糊,过多的 GPU 处理会导致内存问题

# 请使用 html + css 实现以下效果,且不管浏览器如果缩放,始终保持下图在浏览器水平和垂直方向的中间(十字架需css绘制)

题目要求图片 (opens new window)

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>align</title>
	<style type="text/css">
		.container{
            display: flex;
            align-items: center;
            justify-content: center;
            flex-direction: column;
            height: 100%;
            width: 100%;
            background-color: #ccc;
        }
        .top{
            width: 30px;
            height: 50px;
            background-color: #fff;
            border: 2px solid blue;
            border-bottom: 0;
        }
        .middle{
            display: flex;
            background-color: #fff;
        }
        .left, .right{
            width: 50px;
            height: 30px;
            background-color: #fff;
        }
        .left{
            border: 2px solid blue;
            border-right: 0;
            margin-right: 15px;
        }
        .right{
            border: 2px solid blue;
            border-left: 0;
            margin-left: 15px;
        }
        .bottom{
            width: 30px;
            height: 50px;
            background-color: #fff;
            border: 2px solid blue;
            border-top: 0;
        }
	</style>
</head>
<body>
	<div class="container">
        <div class="top"></div>
        <div class="middle">
            <div class="left"></div>
            <div class="right"></div>
        </div>
        <div class="bottom"></div>
    </div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

# 说说CSS选择器以及这些选择器的优先级

  • !important
  • 内联样式(1000)
  • ID选择器(0100)
  • 类选择器/属性选择器/伪类选择器(0010)
  • 元素选择器/伪元素选择器(0001)
  • 关系选择器/通配符选择器(0000)

# 盒模型

标准模型和IE模型的区别

IE盒模型和标准盒模型的总宽度都是由四个部分组成的:margin,border,padding,content

IE 模型包含了content、padding 和 border 的值,而标准盒模型的宽度只有内容 content 部分,是独立的。

box-sizing

box-sizing 属性可以为三个值之一:content-box(default),border-box,padding-box:

  • content-box,border和padding不计算入width之内

  • padding-box,padding计算入width内

  • border-box,border和padding计算入width之内,其实就是怪异模式了

# 你知道什么是BFC么

BFC 全称为块级格式化上下文 (Block Formatting Context) ,可以说BFC就是一个作用范围,把它理解成是一个独立的容器,并且这个容器里box的布局与这个容器外的box毫不相干。

触发BFC的条件:

  • 根元素或其它包含它的元素
  • 浮动元素 (元素的 float 不是 none)
  • 绝对定位元素 (元素具有 position 为 absolute 或 fixed)
  • 内联块 (元素具有 display: inline-block)
  • 表格单元格 (元素具有 display: table-cell,HTML表格单元格默认属性)
  • 表格标题 (元素具有 display: table-caption, HTML表格标题默认属性)
  • 具有overflow 且值不是 visible 的块元素
  • 弹性盒(flex或inline-flex)
  • display: flow-root
  • column-span: all

BFC的约束规则:

  • 内部的盒会在垂直方向一个接一个排列(可以看作BFC中有一个的常规流)
  • 处于同一个BFC中的元素相互影响,可能会发生外边距重叠
  • 每个元素的margin box的左边,与容器块border box的左边相接触(对于从左往右的格式化,否则相反),即使存在浮动也是如此
  • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
  • 计算BFC的高度时,考虑BFC所包含的所有元素,连浮动元素也参与计算
  • 浮动盒区域不叠加到BFC上

BFC可以解决的问题:

  • 防止 margin 重叠 (同一个BFC内的两个两个相邻Box的 margin 会发生重叠,触发生成两个BFC,即不会重叠)
  • 清除内部浮动 (创建一个新的 BFC,因为根据 BFC 的规则,计算 BFC 的高度时,浮动元素也参与计算)
  • 自适应多栏布局,避免某元素被浮动元素覆盖 (BFC的区域不会与float box重叠。因此,可以触发生成一个新的BFC)

# 你对 Flex 布局的了解

容器属性(使用在flex布局容器上的属性)

  • justify-content 定义了子元素在主轴(横轴)上的对齐方式
.container {
    justify-content: center | flex-start | flex-end | space-between | space-around;
    /* 主轴对齐方式:居中 | 左对齐(默认值) | 右对齐 | 两端对齐(子元素间边距相等) | 周围对齐(每个子元素两侧margin相等) */
}
1
2
3
4
  • align-items 定义了定义项目在交叉轴(竖轴)上对齐方式
.container {
    align-items: center | flex-start | flex-end | baseline | stretch;
    /* 侧轴对齐方式:居中 | 上对齐 | 下对齐 | 项目的第一行文字的基线对齐 | 如果子元素未设置高度,将占满整个容器的高度(默认值) */
}
1
2
3
4
  • align-content 定义多根轴线的对齐方式
.container {
    align-content: center | flex-start | flex-end | space-between | space-around | stretch;
    /* 默认值:与交叉轴的中点对齐 | 与交叉轴的起点对齐 | 与交叉轴的终点对齐 | 与交叉轴两端对齐 | 每根轴线两侧的间隔都相等 | (默认值):轴线占满整个交叉轴 */
}
1
2
3
4
  • flex-direction 主轴(横轴)方向
.container {
    flex-direction: row | row-reverse | column | column-reverse;
    /* 主轴方向:水平由左至右排列(默认值) | 水平由右向左 | 垂直由上至下 | 垂直由下至上 */
}
1
2
3
4
  • flex-wrap 换行方式
.container {
    flex-wrap: nowrap | wrap | wrap-reverse;
    /* 换行方式:不换行(默认值) | 换行 | 反向换行 */
}
1
2
3
4
  • flex-flow flex-flow属性是flex-direction属性和flex-wrap的简写
.container {
    flex-flow: <flex-direction> || <flex-wrap>;
    /* 默认值:row nowrap */
}
1
2
3
4

项目属性(使用在容器内子元素上的属性)

  • flex-grow 定义项目的放大比例,默认为0,即使有剩余空间也不放大

如果所有子元素flex-grow为1,那么将等分剩余空间,如果某个子元素flex-grow为2,那么这个子元素将占据2倍的剩余空间

.item {
  flex-grow: <number>; /* default 0 */
}
1
2
3
  • flex-shrink 定义项目的缩小比例,默认为1,即如果空间不足,子元素将缩小。

如果所有子元素flex-shrink都为1,某个子元素flex-shrink为0,那么该子元素将不缩小

.item {
  flex-shrink: <number>; /* default 1 */
}
1
2
3
  • flex-basis 定义在分配多余空间之前,项目占据的主轴空间

默认auto,即子元素本来的大小,如果设定为一个固定的值,那么子元素将占据固定空间

.item {
  flex-basis: <length> | auto; /* default auto */
}
1
2
3
  • flex flex属性是flex-grow, flex-shrink 和 flex-basis的简写

默认值为0 1 auto,即有剩余空间不放大,剩余空间不够将缩小,子元素占据自身大小

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
1
2
3

flex有两个快捷值:auto和none,分别代表1 1 auto(有剩余空间则平均分配,空间不够将等比缩小,子元素占据空间等于自身大小)和0 0 auto(有剩余空间也不分配,空间不够也不缩小,子元素占据空间等于自身大小)

  • order 定义项目的排列顺序。数值越小,排列越靠前,默认为0
.item {
  order: <integer>;
}
1
2
3
  • align-self 定义单个子元素的排列方式

例如align-items设置了center,使得所有子元素居中对齐,那么可以通过给某个子元素设置align-self来单独设置子元素的排序方式

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
1
2
3

参考资料: 阮一峰Flex布局 (opens new window)

# 清楚浮动的方法有哪些?

  1. 使用额外的空元素清除浮动:

在浮动元素的父元素的末尾添加一个空的块级元素,并为其设置样式 clear: both;。这会使父元素自动适应浮动元素的高度。

<div class="parent">
  <div class="float-left"></div>
  <div class="float-left"></div>
  <div style="clear: both;"></div>
</div>

1
2
3
4
5
6

这种方法简单易用,但需要添加额外的 HTML 元素。

  1. 使用伪元素清除浮动:

使用伪元素 ::after 在浮动元素的父元素中插入一个空的块级元素,并为其设置样式 clear: both;

.parent::after {
  content: "";
  display: table;
  clear: both;
}

1
2
3
4
5
6

这种方法不需要添加额外的 HTML 元素,但需要在 CSS 中定义伪元素的样式。

  1. 使用 clearfix 类清除浮动:

定义一个 .clearfix 类,并为其设置样式 overflow: auto; 或 overflow: hidden;。然后将该类应用于浮动元素的父元素。

.clearfix::after {
  content: "";
  display: table;
  clear: both;
}

.clearfix {
  overflow: auto;
}
    
1
2
3
4
5
6
7
8
9
10

在父元素中添加 .clearfix 类,可以清除浮动并保持父元素的高度正常。

  1. 使用 CSS 弹性布局(Flexbox):

将父元素设置为 display: flex;,这样子元素将自动成为弹性项目,并根据需要进行自动伸缩。

.parent {
  display: flex;
}

1
2
3
4

使用 Flexbox 布局可以更方便地管理浮动元素,并自动解决高度塌陷的问题。

# 说说你对 HTML 语义化的理解 ?

HTML 语义化是指我们在写 HTML 结构时用有英文语义的标签,使 HTML 更易于开发人员和机器的阅读和理解。

非语义元素的例子:

是没有语义的标签

语义元素示例:

、、